package com.sysware.designpattern.proxy.jdkdynproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import com.sysware.designpattern.proxy.IUserDao;

/**
 * jdk动态代理
 * 
 * @author spc-00d
 *
 */
public class App {

	public static void main(String[] args) {
		/**
		 * 不直接调用对象，而是通过它的代理对象去掉用
		 */
		IUserDao target1 = new UserDao();
		IUserDao dao1 = (IUserDao) ProxyFactory.createProxyInstance(target1);
		dao1.save();
	}

	/**
	 * 使用反射直接调用方法
	 * 
	 * @param args
	 */
	public static void main1(String[] args) {
		try {
			Class<UserDao> clazz = UserDao.class;
			Method method = clazz.getMethod("save");
			method.invoke(clazz.newInstance());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 使用JDK代理调用
	 * 
	 * @param args
	 */
	public static void main2(String[] args) {
		// Class<?> beProxyedClass = UserDao.class;
		IUserDao target = new UserDao();

		InvocationHandler handler = new InvocationHandler() {
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				System.out.println("开始事务2");
				// 执行目标对象方法
				Object returnValue = method.invoke(target, args);
				System.out.println("提交事务2");
				return returnValue;
			}
		};

		Object obj = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
				handler);
		if (obj != null) {
			IUserDao dao = (IUserDao) obj;
			dao.save();
		}

	}

}

class UserDao implements IUserDao {
	@Override
	public void save() {
		System.out.println("----已经保存数据!----");
	}
}

class ProxyFactory {

	// 给目标对象生成代理对象
	public static Object createProxyInstance(Object target) {
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
				new InvocationHandler() {
					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						System.out.println("开始事务2");
						// 执行目标对象方法
						Object returnValue = method.invoke(target, args);
						System.out.println("提交事务2");
						return returnValue;
					}
				});
	}

}